package com.lazy.book.service.system.impl;

import cn.hutool.core.bean.BeanUtil;
import com.lazy.book.common.entity.PageResult;
import com.lazy.book.common.enums.CommonResponseEnum;
import com.lazy.book.common.utils.PageUtils;
import com.lazy.book.common.utils.Utils;
import com.lazy.book.mapper.system.SysDeptLeaderMapper;
import com.lazy.book.mapper.system.SysDeptMapper;
import com.lazy.book.mapper.system.SysUserMapper;
import com.lazy.book.pojo.entity.SelectIdsDTO;
import com.lazy.book.pojo.system.pojo.dto.common.SelectorQueryDTO;
import com.lazy.book.pojo.system.pojo.dto.sysdept.SysDeptCreateDTO;
import com.lazy.book.pojo.system.pojo.dto.sysdept.SysDeptListDTO;
import com.lazy.book.pojo.system.pojo.dto.sysdept.SysDeptUpdateDTO;
import com.lazy.book.pojo.system.pojo.po.SysDept;
import com.lazy.book.pojo.system.pojo.po.SysDeptLeader;
import com.lazy.book.pojo.system.pojo.vo.common.DepartmentVO;
import com.lazy.book.pojo.system.pojo.vo.sysdept.DeptTreeVO;
import com.lazy.book.pojo.system.pojo.vo.sysdept.SysDeptLeaderVO;
import com.lazy.book.pojo.system.pojo.vo.sysdept.SysDeptVO;
import com.lazy.book.service.system.SysDeptClosureService;
import com.lazy.book.service.system.SysDeptLeaderService;
import com.lazy.book.service.system.SysDeptService;
import com.mybatisflex.core.logicdelete.LogicDeleteManager;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.core.query.QueryMethods;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;



/**
 * <p>
 * 部门表 服务实现类
 * </p>
 *
 * @author sz
 * @since 2024-03-20
 */
@Service
@RequiredArgsConstructor
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {

    private final SysUserMapper userMapper;

    private final SysDeptLeaderMapper leaderMapper;

    private final SysDeptLeaderService deptLeaderService;

    private final SysDeptClosureService deptClosureService;

    @Transactional
    @Override
    public void create(SysDeptCreateDTO dto) {
        SysDept sysDept = BeanUtil.copyProperties(dto, SysDept.class);
        save(sysDept);
        Long deptId = sysDept.getId();
        // 保存部门领导
        if (Utils.isNotEmpty(dto.getLeaderIds())) {
            List<SysDeptLeader> leaders = dto.getLeaderIds().stream().map(userId -> {
                SysDeptLeader leader = new SysDeptLeader();
                leader.setDeptId(deptId);
                leader.setUserId(userId);
                return leader;
            }).collect(Collectors.toList());
            deptLeaderService.saveBatch(leaders);
        }
        // 更新部门祖先表
        if (!sysDept.getParentId().equals(0L)) {
            deptClosureService.insertDeptClosure(sysDept.getParentId(), deptId);
        }
    }

    @Transactional
    @Override
    public void update(SysDeptUpdateDTO dto) {
        SysDept sysDept = BeanUtil.copyProperties(dto, SysDept.class);
        updateById(sysDept);
        Long deptId = sysDept.getId();
        // 先删除原有的部门领导
        QueryWrapper wrapper = QueryWrapper.create().from(SYS_DEPT_LEADER).where(SYS_DEPT_LEADER.DEPT_ID.eq(deptId));
        deptLeaderService.remove(wrapper);
        // 重新保存部门领导
        if (Utils.isNotEmpty(dto.getLeaderIds())) {
            List<SysDeptLeader> leaders = dto.getLeaderIds().stream().map(userId -> {
                SysDeptLeader leader = new SysDeptLeader();
                leader.setDeptId(deptId);
                leader.setUserId(userId);
                return leader;
            }).collect(Collectors.toList());
            deptLeaderService.saveBatch(leaders);
        }
    }

    @Override
    public PageResult<SysDeptVO> page(SysDeptListDTO dto) {
        QueryWrapper wrapper = QueryWrapper.create().from(SYS_DEPT);
        if (Utils.isNotBlank(dto.getDeptName())) {
            wrapper.and(SYS_DEPT.DEPT_NAME.like(dto.getDeptName()));
        }
        Page<SysDept> page = page(dto.buildPage(), wrapper);
        return PageUtils.getPageResult(page);
    }

    @Override
    public List<SysDeptVO> list(SysDeptListDTO dto) {
        QueryWrapper wrapper = QueryWrapper.create().from(SYS_DEPT);
        if (Utils.isNotBlank(dto.getDeptName())) {
            wrapper.and(SYS_DEPT.DEPT_NAME.like(dto.getDeptName()));
        }
        return list(wrapper).stream().map(sysDept -> BeanCopyUtils.copy(sysDept, SysDeptVO.class)).collect(Collectors.toList());
    }

    @Override
    public void remove(SelectIdsDTO dto) {
        CommonResponseEnum.INVALID_ID.assertIsFalse(dto.getIds().isEmpty());
        removeByIds(dto.getIds());
    }

    @Override
    public SysDeptVO detail(Object id) {
        SysDept sysDept = getById((Serializable) id);
        return BeanUtil.copyProperties(sysDept, SysDeptVO.class);
    }

    @Override
    public List<DeptTreeVO> getDepartmentTreeWithAdditionalNodes() {
        return null;
    }

    @Override
    public List<DeptTreeVO> getDeptTree(Integer excludeNodeId, Boolean appendRoot, Boolean needSetTotal) {
        return null;
    }

    @Override
    public SysDeptLeaderVO findSysUserDeptLeader() {
        return null;
    }

    private static QueryWrapper buildQueryWrapper(SysDeptListDTO dto) {
        return QueryWrapper.create().from(SysDept.class);
    }

    @Override
    public List<DepartmentVO> listSelector(SelectorQueryDTO dto) {
        QueryWrapper wrapper = QueryWrapper.create().select(SYS_DEPT.ID, SYS_DEPT.PID, SYS_DEPT.NAME, SYS_DEPT.SORT, SYS_DEPT.DEEP)
                .orderBy(SYS_DEPT.SORT.asc());
        // 获取所有部门信息
        List<DepartmentVO> list = listAs(wrapper, DepartmentVO.class);
        return TreeUtils.buildTree(list, 0);
    }

}